#include "myString.hpp"
#define BASE_SIZE (size_t)15
//MyString

MyString::MyString():start(new char[BASE_SIZE + 1]()), end_of_storage(start+BASE_SIZE), finish(start){
    std::cout<<"MyString()"<<std::endl;
}

MyString::MyString(size_t num, char c){
    size_t res = std::max(BASE_SIZE, num);
    start = new char[res + 1]();
    end_of_storage = start + res;
    finish = start + num;
    memset(start, c, num);
}
MyString::MyString(const char *str){
    size_t len = strlen(str);
    size_t res = std::max(BASE_SIZE, len);
    start = new char[res + 1]();
    end_of_storage = start + res;
    finish = start + len;
    memcpy(start, str, len);
    std::cout<<"MyString(const char *str)"<<std::endl;

}

MyString::MyString(const MyString &rhs){
    size_t len = rhs.size();
    size_t res = std::max(BASE_SIZE, len);
    start = new char[res + 1]();
    end_of_storage = start + res;
    finish = start + len;
    memcpy(start, rhs.start, len);
    std::cout<<"MyString(const MyString &rhs)"<<std::endl;
}

MyString::~MyString(){
    if(start){
        delete [] start;
        start = nullptr;
        end_of_storage = nullptr;
        finish = nullptr;
        std::cout<<"~MyString"<<std::endl;
    }
}

MyString &MyString::operator=(const MyString &rhs){
    if(this != &rhs){
        if(start){
            delete [] start;
        }
        start = new char[rhs.capacity() + 1]();
        memcpy(start, rhs.start, rhs.size());
        end_of_storage = start + rhs.capacity();
        finish = start + rhs.size();
    }
    std::cout<<"MyString operator=(const MyString &rhs)"<<std::endl;
    return *this;
}
MyString &MyString::operator=(const char *str){
    if(start != str){
        if(start){
            delete [] start;
        }
        size_t len = strlen(str);
        start = new char[len + 1]();
        memcpy(start, str, len);
        end_of_storage = start + len;
        finish = start + len;
    }
    std::cout<<"MyString operator=(const char *str)"<<std::endl;
    return *this;
}

MyString MyString::operator+(const char *str){
    MyString temp(*this);
    return temp.append(str);

}

MyString MyString::operator+(const MyString &rhs){
    return (*this) + rhs.start;
}

MyString operator+(const char *str, const MyString &rhs){
    MyString temp(str);
    return temp.append(rhs);
}

char &MyString::operator[](const size_t index){
    return *(start + index);
}

const char &MyString::operator[](std::size_t index) const{
    return *(start + index);
}

bool MyString::operator==(const char *str)const{
    if(strcmp(str, start) == 0){
        return true;
    }
    return false;
}

bool operator==(const char *str, const MyString &rhs){
    if(strcmp(str, rhs.start) == 0){
        return true;
    }
    return false;
}

bool MyString::operator==(const MyString &rhs)const{
    if(strcmp(rhs.start, start) == 0){
        return true;
    }
    return false;
}

bool operator!=(const MyString &rhs1, const MyString &rhs2){
    return !(rhs1 == rhs2);
}

bool MyString::operator>(const MyString &rhs){
    std::cout<<"bool MyString::operator>(const MyString &rhs)"<<std::endl;
    return (*this > rhs.start);
}
bool MyString::operator>(const char *str){
    std::cout<<"bool MyString::operator>(const char *str)"<<std::endl;
    return (strcmp(this->start, str) > 0);
}
bool operator>(const char* str, const MyString &rhs){
    std::cout<<"bool operator>(const char *str, const MyString &rhs)"<<std::endl;
    return (strcmp(str, rhs.start) > 0);
}

bool MyString::operator<(const MyString &rhs){
    std::cout<<"bool MyString::operator<(const MyString &rhs)"<<std::endl;
    return (*this < rhs.start);

}
bool MyString::operator<(const char *str){
    std::cout<<"bool MyString::operator<(const char *str)"<<std::endl;
    return (strcmp(start, str) < 0);

}
bool operator<(const char* str, const MyString &rhs){
    std::cout<<"bool operator<(const char *str, const MyString &rhs)"<<std::endl;
    return (strcmp(str, rhs.start) < 0);
}

bool operator<=(const MyString &rhs1, const MyString &rhs2){
    std::cout<<"bool operator<=(const MyString &rhs1, const MyString &rhs2)"<<std::endl;
    return (strcmp(rhs1.start, rhs2.start) <= 0);
}

bool operator>=(const MyString &rhs1, const MyString &rhs2){
    std::cout<<"bool operator<=(const MyString &rhs1, const MyString &rhs2)"<<std::endl;
    return (strcmp(rhs1.start, rhs2.start) <= 0);
}

std::ostream &operator<<(std::ostream & os, const MyString &rhs){
    return os<<(rhs.start);
}

std::istream &operator>>(std::istream &is, MyString &rhs){
    char ch;
    while(is.get(ch) && isspace(ch));
    rhs.clear();

    do{
        rhs.push_back(ch);

    }while(is.get(ch) && !isspace(ch));


    if(isspace(ch))  is.putback(ch);
    return is;
}

MyString &MyString::append(const char *str){
    for(const char *p = str; (*p) != 0; p++){
        push_back(*p);
    }
    return *this;
}

MyString &MyString::append(const MyString &rhs){
    return append(rhs.start);
}

char &MyString::at(const size_t index)const{
    //越界检测
    return *(start + index);
}

void MyString::clear(){
    memset(start, 0, size());
    finish = start;
}

bool MyString::empty()const{
    return start == finish;
}

size_t MyString::size()const{
    return finish - start;
}

size_t MyString::capacity() const{
    return end_of_storage - start;
}

MyString &MyString::reserve(size_t num){
    char *news = new char[num + 1]();
    memcpy(news, start, num);
    end_of_storage = news + num;
    finish = news + std::min(size(), num);
    delete [] start;
    start = news;
    return *this;
}
void MyString::push_back(char ch){
    if(end_of_storage == finish){
        reserve(2 * size());
    }
    *finish = ch;
    ++finish;
}

const char * MyString::c_str() const{
    return start;
}










